package com.exit66.jukebox.data;

/**
 * @author andyb
 *
 * To change this generated comment edit the template variable "typecomment":
 * Window>Preferences>Java>Templates.
 * To enable and disable the creation of type comments go to
 * Window>Preferences>Java>Code Generation.
 */

import java.io.DataOutputStream;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import com.exit66.jukebox.Options;
import com.exit66.jukebox.util.Lock;
import com.exit66.jukebox.util.XmlSegment;

public class Album extends BVDatabaseObject {
    
    private int		_albumID = -1;
    private String	_albumName;
    private int		_multipleArtistID = -1;
    private Artist      _multipleArtist = null;
    private int         _artistCount = 0;
    private static Lock _findSaveLock = new Lock();
    
    public int getAlbumID() {
        
        return _albumID;
        
    }
    
    public void setAlbumID(int newValue) {
        
        _albumID = newValue;
        
    }
    
    public String getAlbumName() {
        
        return _albumName;
        
    }
    
    public void setAlbumName(String newValue) {
        
        if (newValue != null)
            _albumName = newValue.trim();
        else
            _albumName = null;
        
    }
    
    public Artist getMultipleArtist() {
        if ((_multipleArtist == null) || (_multipleArtistID != _multipleArtist.getArtistID())) {
            if (_multipleArtistID != -1) {
                _multipleArtist = new Artist();
                _multipleArtist.setArtistID(_multipleArtistID);
                _multipleArtist.fetch();
            } else {
                _multipleArtist = new Artist();
            }
        }
        
        return _multipleArtist;
    }
    
    public int getMultipleArtistID() {
        
        return _multipleArtistID;
        
    }
    
    public void setMultipleArtistID(int newValue) {
        
        _multipleArtistID = newValue;
        
    }
    
    public void setArtistCount(int newValue) {
        _artistCount = newValue;
    }
    
    public int getArtistCount() {
        return _artistCount;
    }
    
    public boolean fetch() {
        
        if (openConnection()) {
            
            ResultSet rs = retrieveData("SELECT * FROM album WHERE album_id = " + _albumID);
            
            try {
                
                if (rs.next()) {
                    
                    _albumName = rs.getString("album_name");
                    _multipleArtistID = rs.getInt("multiple_artist_id");
                    _artistCount = rs.getInt("artist_count");
               
                    
                } else {
                    
                    _albumName = "";
                    _multipleArtistID = -1;
                    _artistCount = 0;
                    return false;
                    
                }
                
            } catch (SQLException e) {
                
                System.err.println(e);
                
            }
            
            closeConnection();
            
            return true;
            
        } else {
            
            return false;
            
        }
        
    }
    
    public synchronized void findAndSave() {
        _findSaveLock.lock();
        if (!find()) {
            save();
        }
        _findSaveLock.releaseLock();
    }
    
    public void save(boolean findAlbum) {
        
        ResultSet rs;
        
        if (openConnection()) {
            
            try {

                if ((findAlbum == true) && (_albumID == -1)) {
                    
                    this.find();
                    
                }
                
                if (_albumID == -1) {
                    
                    rs = retrieveData("INSERT INTO album (album_name, multiple_artist_id) VALUES (" +
                            Qts(_albumName) + ", " + _multipleArtistID + "); CALL IDENTITY()");
                    
                    try {
                        
                        if (rs.next()) {
                            
                            _albumID = rs.getInt(1);
                            
                        }
                        
                    } catch (SQLException e) {
                        
                        System.err.println(e);
                        
                    }
                    
                } else {
                    
                    executeStatement("UPDATE album SET album_name = " + Qts(_albumName) + ", " +
                            "multiple_artist_id = " + _multipleArtistID +
                            " WHERE album_id = " + _albumID);
                    
                }
            } catch (Exception e) {
                
                System.err.println(e);
                
            }
            
            closeConnection();
            
        }
        
    }
    
    public void save() {
        
        save(true);
    }
    
    public void remove() {
        
        if (openConnection()) {
            
            executeStatement("DELETE FROM album WHERE album_id = " + _albumID);
            
            executeStatement("DELETE FROM track WHERE album_id = " + _albumID);
            
            executeStatement("DELETE FROM artistalbumlink WHERE album_id = " + _albumID);
            
            executeStatement("DELETE FROM artist WHERE artist_id NOT IN (SELECT artist_id FROM artistalbumlink)");
            
            closeConnection();
        }
        
    }
    
    public boolean find() {
        
        openConnection();
        
        ResultSet rs = retrieveData("SELECT * FROM album WHERE album_name = " + Qts(_albumName));
        
        try {
            
            if (rs != null && rs.next()) {
                
                closeConnection();
                _albumID = rs.getInt("album_id");
                _multipleArtistID = rs.getInt("multiple_artist_id");
                _artistCount = rs.getInt("artist_count");
                return true;
                
            }
            
        } catch (SQLException e) {
            
            System.err.println(e);
            
        }
        
        closeConnection();
        return false;
        
    }
    
    public boolean findForArtist(int artistID) {
        
        openConnection();
        
        ResultSet rs = retrieveData("SELECT album.* FROM album JOIN artistalbumlink " + 
        		"ON album.album_id = artistalbumlink.album_id WHERE album_name = " + Qts(_albumName) + 
        		" AND artistalbumlink.artist_id = " + artistID);
        
        try {
            
            if (rs != null && rs.next()) {
                
                closeConnection();
                _albumID = rs.getInt("album_id");
                _multipleArtistID = rs.getInt("multiple_artist_id");
                _artistCount = rs.getInt("artist_count");
                return true;
                
            }
            
        } catch (SQLException e) {
            
            System.err.println(e);
            
        }
        
        closeConnection();
        return false;
        
    } 
    public Properties getProperties(Properties prop) {
        
        prop.setProperty("album_id", String.valueOf(_albumID));
        prop.setProperty("album_name", noNull(_albumName));
        prop.setProperty("multiple_artist_id", String.valueOf(_multipleArtistID));
        
        return prop;
        
    }
    
    public int findArtistID() {
        
        int count = 0;
        int artistID = -1;
        
        if (_multipleArtistID != -1) {
            
            return _multipleArtistID;
            
        }
        
        ResultSet rs = retrieveData("SELECT DISTINCT artist_id FROM track WHERE album_id = " + String.valueOf(_albumID));
        
        try {
            
            while (rs.next()) {
                
                artistID = rs.getInt("artist_id");
                count++;
                
            }
            
            if (count != 1) {
                
                return -1;
                
            } else {
                
                return artistID;
                
            }
            
        } catch (SQLException e) {
            
            System.err.println(e);
            return -1;
            
        }
        
    }
    
    public void split() {
        
        fetch();
        
        ResultSet rs = retrieveData("SELECT DISTINCT artist_id FROM artistalbumlink WHERE album_id = " + String.valueOf(_albumID));
        
        try {
            
            Album album = new Album();
            
            rs.next(); // skip the first one, we're leaving it as is
            
            while (rs.next()) {
                
                album.setAlbumID(-1);
                album.setAlbumName(_albumName);
                album.save(false);
                
                executeStatement("UPDATE artistalbumlink SET album_id = " +
                        String.valueOf(album.getAlbumID()) + " WHERE album_id = " +
                        String.valueOf(_albumID) + " AND artist_id = " +
                        String.valueOf(rs.getInt("artist_id")));
                
                executeStatement("UPDATE track SET album_id = " +
                        String.valueOf(album.getAlbumID()) + " WHERE album_id = " +
                        String.valueOf(_albumID) + " AND artist_id = " +
                        String.valueOf(rs.getInt("artist_id")));
                
            }
            
        } catch (SQLException e) {
            
            System.err.println(e);
            
        }
        
    }
    
    public Track getFirstTrackForAlbum() {
        
        try {
            
            ResultSet rs = retrieveData("SELECT track_id FROM track WHERE album_id = " +
                    _albumID + " ORDER BY track_number, track_name");
            
            if (rs.next()) {
                
                Track t = new Track();
                
                t.setTrackID(rs.getInt("track_id"));
                t.fetch();
                return t;
                
            }
            
        } catch (Exception e) {
            
            System.err.println(e);
            
        }
        
        return null;
        
    }
    
    public void getCoverImage(DataOutputStream os, boolean showNotFound) {
        
        try {
            
            ResultSet rs = retrieveData("SELECT track_id FROM track WHERE album_id = " +
                    _albumID + " ORDER BY track_number, track_name");
            
            if (rs.next()) {
                
                Track t = new Track();
                
                t.setTrackID(rs.getInt("track_id"));
                t.fetch();
                t.getCoverImage(os, showNotFound);
                return;
                
            }
            
        } catch (Exception e) {
            
            System.err.println(e);
            
        }
        
        if (showNotFound) {
            Options.outputDefaultImage(os);
        }
        
    }
    
    public XmlSegment returnXml(boolean expandChildren) {
        return returnXml(true, true, false, false);        
    }
    
    public XmlSegment returnXml(boolean expandArtist, boolean expandTracks, 
                boolean expandTrackArtist, boolean expandTrackAlbum) {
        XmlSegment xml = new XmlSegment();
        xml.startNode("album");
        xml.writeNode("id", String.valueOf(_albumID));
        xml.writeNode("name", _albumName);
        xml.writeNode("multipleArtistId", String.valueOf(_multipleArtistID));
        xml.writeNode("artistCount", String.valueOf(_artistCount));
        if (expandArtist) {
            if (_multipleArtistID != -1) {
                xml.appendSegment(getMultipleArtist().returnXml(false));
            }
        }
        if (expandTracks) {
            TrackCollection list = new TrackCollection();
            list.listByAlbum(_albumID, 0, 0);
            
            while (!list.isEOF()) {
                Track track = (Track)list.getCurrent();
                xml.appendSegment(track.returnXml(expandTrackArtist, expandTrackAlbum));
                list.moveNext();
            }
        }
        xml.endNode("album");
        
        return xml;
    }
    
    public static Album getAlbumFromId(int albumId) {
    	Album album = new Album();
    	album.setAlbumID(albumId);
    	if (album.fetch())
    		return album;
    	else
    		return null;    	
    }
    
    
    
}
